# -*- Mode: Makefile -*-

###
### This is the standard include file for building example programs.
### Any makefile that includes this one must define the following
### variables first:
###
###   $(CHOMBO_HOME)   absolute path to the Chombo "lib" directory
###   $(LibNames)      names of the Chombo libraries to use
###   $(mdebase)         names of the programs to build
###   $(base_dir)      relative path to directory containing $(mdebase) src files (default: .)
###   $(src_dirs)      relative paths to other directories containing source
###                    files to be compiled into the $(mdebase) programs
###   $(INPUT)         arguments to program (default: $(mdebase).input)
###   $(VERBOSE)       arguments to program to control verbosity (default: -q)
###
### followed by:
###
###   include $(CHOMBO_HOME)/mk/Make.example
###
### The names in $(mdebase) should be the basenames of the source file
### containing the main() function of the program.  As with the test
### programs, if there is one name in $(mdebase), all the sources in the
### subdirectory are compiled together into one program.  If there are
### two or more names in $(mdebase), then each program is built from only
### the source file corresponding to the name in $(base_dir), plus the
### sources in $(src_dirs).
###
### Note: all source files in $(src_dirs) are used, so to keep a source
###       file in a directory without compiling it, it must be renamed
###       so it doesn't have a known source file extension (see the
###       $(src_extensions) variable).  The extension ".notused" is
###       recommended for this purpose.
###
######################################################################

makefiles+=Make.example.multidim

# define basic make variables
include $(CHOMBO_HOME)/mk/Make.defs

# define configuration variables
#[NOTE: Make.rules also includes this file, but we need it here first.]
include $(CHOMBO_HOME)/mk/Make.defs.config

# take care of dimension-specific libraries
_1dlib_names := $(shell echo $(1dLibNames) | tr 'A-Z' 'a-z')
_2dlib_names := $(shell echo $(2dLibNames) | tr 'A-Z' 'a-z')
_3dlib_names := $(shell echo $(3dLibNames) | tr 'A-Z' 'a-z')
_4dlib_names := $(shell echo $(4dLibNames) | tr 'A-Z' 'a-z')
_5dlib_names := $(shell echo $(5dLibNames) | tr 'A-Z' 'a-z')
_6dlib_names := $(shell echo $(6dLibNames) | tr 'A-Z' 'a-z')

# if we're building the libraries, need to specify LibNames variable
# appropriately (1dLibNames, etc hopefully set by application makefile)
ifeq ($(DIM),1)
LibNames = $(1dLibNames)
endif

ifeq ($(DIM),2)
LibNames = $(2dLibNames)
endif

ifeq ($(DIM),3)
LibNames = $(3dLibNames)
endif

ifeq ($(DIM),4)
LibNames = $(4dLibNames)
endif

ifeq ($(DIM),5)
LibNames = $(5dLibNames)
endif

ifeq ($(DIM),6)
LibNames = $(6dLibNames)
endif

#create names of actual library files (for dependencies)
1dlibs = $(patsubst %,$(CHOMBO_HOME)/lib%$(1dconfig).a,$(_1dlib_names))
2dlibs = $(patsubst %,$(CHOMBO_HOME)/lib%$(2dconfig).a,$(_2dlib_names))
3dlibs = $(patsubst %,$(CHOMBO_HOME)/lib%$(3dconfig).a,$(_3dlib_names))
4dlibs = $(patsubst %,$(CHOMBO_HOME)/lib%$(4dconfig).a,$(_4dlib_names))
5dlibs = $(patsubst %,$(CHOMBO_HOME)/lib%$(5dconfig).a,$(_5dlib_names))
6dlibs = $(patsubst %,$(CHOMBO_HOME)/lib%$(6dconfig).a,$(_6dlib_names))

all_libs = $(subst FALSE,,$(subst TRUE,$(6dlibs),$(USE_6D)))\
$(subst FALSE,,$(subst TRUE,$(5dlibs),$(USE_5D)))\
$(subst FALSE,,$(subst TRUE,$(4dlibs),$(USE_4D)))\
$(subst FALSE,,$(subst TRUE,$(3dlibs),$(USE_3D)))\
$(subst FALSE,,$(subst TRUE,$(2dlibs),$(USE_2D)))\
$(subst FALSE,,$(subst TRUE,$(1dlibs),$(USE_1D)))\

1dlibflags = $(patsubst %,-l%$(1dconfig),$(_1dlib_names))
2dlibflags = $(patsubst %,-l%$(2dconfig),$(_2dlib_names))
3dlibflags = $(patsubst %,-l%$(3dconfig),$(_3dlib_names))
4dlibflags = $(patsubst %,-l%$(4dconfig),$(_4dlib_names))
5dlibflags = $(patsubst %,-l%$(5dconfig),$(_5dlib_names))
6dlibflags = $(patsubst %,-l%$(6dconfig),$(_6dlib_names))

all_dimension_libs = $(subst FALSE,,$(subst TRUE,$(6dlibflags),$(USE_6D)))\
$(subst FALSE,,$(subst TRUE,$(5dlibflags),$(USE_5D)))\
$(subst FALSE,,$(subst TRUE,$(4dlibflags),$(USE_4D)))\
$(subst FALSE,,$(subst TRUE,$(3dlibflags),$(USE_3D)))\
$(subst FALSE,,$(subst TRUE,$(2dlibflags),$(USE_2D)))\
$(subst FALSE,,$(subst TRUE,$(1dlibflags),$(USE_1D)))\

src_dirs = $(1dsrc_dirs) $(2dsrc_dirs) $(3dsrc_dirs) $(4dsrc_dirs) $(5dsrc_dirs) $(6dsrc_dirs) $(mdsrc_dirs)

# tell Make.rules to search source directories for include files
appcppflags := -I$(base_dir) $(addprefix -I,$(src_dirs))

# for multidim, need to remove Chombo lib/src directories from include path
# and also remove spacedim
MDCPPFLAGS :=  -DCH_$(system)\
$(subst FALSE,,$(subst TRUE,$(cppdbgflags),$(DEBUG)))\
$(subst FALSE,,$(subst TRUE,$(cppoptflags),$(subst HIGH,$(cppoptflags) -DNDEBUG,$(OPT))))\
$(cppcomflags)\
$(subst FALSE,,$(subst TRUE,-DCH_MPI $(mpicppflags),$(MPI)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE_SETVAL,$(USE_SETVAL)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE_COMPLEX,$(USE_COMPLEX)))\
$(subst FALSE,,$(subst TRUE,-DCH_NAMESPACE,$(NAMESPACE)))\
$(subst FALSE,,$(subst TRUE,-DCH_MULTIDIM,$(MULTIDIM)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE1D,$(USE_1D)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE2D,$(USE_2D)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE3D,$(USE_3D)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE4D,$(USE_4D)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE5D,$(USE_5D)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE6D,$(USE_6D)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE_MEMORY_TRACKING,$(USE_MT)))\
$(subst FALSE,-DCH_NTIMER,$(subst TRUE,,$(USE_TIMER)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE_64,$(USE_64)))\
$(subst DOUBLE,-DCH_USE_DOUBLE,$(subst FLOAT,-DCH_USE_FLOAT,$(PRECISION)))\
$(subst FALSE,,$(subst TRUE,-DCH_USE_HDF5 $(subst FALSE,$(HDFINCFLAGS),$(subst TRUE,$(HDFMPIINCFLAGS),$(MPI))),$(USE_HDF)))\
$(cxxcppflags) $(fcppflags) $(appcppflags) $(cppcallsfort) \
$(subst FALSE,,$(subst TRUE,$(fftincflags),$(USE_FFTW)))\
$(subst FALSE,,$(subst TRUE, -DCH_USE_PETSC $(petscincflags),$(USE_PETSC)))\
$(subst FALSE,,$(subst TRUE,-I$(CHOMBO_HOME)/include/multidim,$(MULTIDIM)))\

# over-ride libflags -- for now, do this explicitly for 1,2,3,4,5,6D

MDLIBFLAGS := -L$(CHOMBO_HOME) \
$(all_dimension_libs) \
$(subst FALSE,,$(subst TRUE,$(mpilibflags),$(MPI)))\
$(subst FALSE,,$(subst TRUE,$(subst FALSE,$(HDFLIBFLAGS),$(subst TRUE,$(HDFMPILIBFLAGS),$(MPI))),$(USE_HDF)))\
$(subst FALSE,,$(subst TRUE,$(fftlibflags),$(USE_FFTW)))\
$(subst FALSE,,$(subst TRUE,$(petsclibflags),$(USE_PETSC)))\
$(subst FALSE,,$(subst TRUE,$(PAPILIBDIR) -lpapi,$(USE_PAPI)))\
$(flibflags) $(syslibflags)

# names of subdirectories used for compilation files -- there's probably a 
# cleverer way to do this, but use brute force for now...
_1dobject_prefix  = o/$(1dconfig)/
_1dfortran_prefix = f/$(1dconfig)/
_1ddepends_prefix = d/$(1dconfig)/

_2dobject_prefix  = o/$(2dconfig)/
_2dfortran_prefix = f/$(2dconfig)/
_2ddepends_prefix = d/$(2dconfig)/

_3dobject_prefix  = o/$(3dconfig)/
_3dfortran_prefix = f/$(3dconfig)/
_3ddepends_prefix = d/$(3dconfig)/

_4dobject_prefix  = o/$(4dconfig)/
_4dfortran_prefix = f/$(4dconfig)/
_4ddepends_prefix = d/$(4dconfig)/

_5dobject_prefix  = o/$(5dconfig)/
_5dfortran_prefix = f/$(5dconfig)/
_5ddepends_prefix = d/$(5dconfig)/

_6dobject_prefix  = o/$(6dconfig)/
_6dfortran_prefix = f/$(6dconfig)/
_6ddepends_prefix = d/$(6dconfig)/

_mdobject_prefix  = o/$(newconfig)/
_mdfortran_prefix = f/$(newconfig)/
_mddepends_prefix = d/$(newconfig)/

# get all the source files in this application
#[NOTE: src_extensions and vpath should match $(src_wildcard) in Make.rules;
#       they are defined here explicitly because Make.rules isn't loaded. <dbs>]
src_extensions := .cpp .ChF .F .f .c
vpath %.cpp $(src_dirs)
vpath %.ChF $(src_dirs)
vpath %.F   $(src_dirs)
vpath %.f   $(src_dirs)
vpath %.c   $(src_dirs)
vpath %.d d/$(1dconfig) d/$(2dconfig) d/$(3dconfig) d/$(4dconfig) d/$(5dconfig) d/$(6dconfig) d/$(mdconfig) .

# first off, set the default location of the main source file
ifeq ($(base_dir),)
  base_dir = .
endif

# list of source files in all the other source directories
ifneq ($(1dsrc_dirs),)
  _1dsrcs := $(notdir $(wildcard $(foreach ext,$(src_extensions),$(addsuffix /*$(ext),$(1dsrc_dirs)))))
endif

ifneq ($(2dsrc_dirs),)
  _2dsrcs := $(notdir $(wildcard $(foreach ext,$(src_extensions),$(addsuffix /*$(ext),$(2dsrc_dirs)))))
endif

ifneq ($(3dsrc_dirs),)
  _3dsrcs := $(notdir $(wildcard $(foreach ext,$(src_extensions),$(addsuffix /*$(ext),$(3dsrc_dirs)))))
endif

ifneq ($(4dsrc_dirs),)
  _4dsrcs := $(notdir $(wildcard $(foreach ext,$(src_extensions),$(addsuffix /*$(ext),$(4dsrc_dirs)))))
endif

ifneq ($(5dsrc_dirs),)
  _5dsrcs := $(notdir $(wildcard $(foreach ext,$(src_extensions),$(addsuffix /*$(ext),$(5dsrc_dirs)))))
endif

ifneq ($(6dsrc_dirs),)
  _6dsrcs := $(notdir $(wildcard $(foreach ext,$(src_extensions),$(addsuffix /*$(ext),$(6dsrc_dirs)))))
endif


ifneq ($(mdsrc_dirs),)
  _mdsrcs := $(notdir $(wildcard $(foreach ext,$(src_extensions),$(addsuffix /*$(ext),$(mdsrc_dirs)))))
endif

# the list of dependency files that Make.rules will need to build, including files in $base_dir
1ddepends := $(addprefix $(_1ddepends_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.d,$(filter %$(_ext),$(_1dsrcs)))))
2ddepends := $(addprefix $(_2ddepends_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.d,$(filter %$(_ext),$(_2dsrcs)))))
3ddepends := $(addprefix $(_3ddepends_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.d,$(filter %$(_ext),$(_3dsrcs)))))
4ddepends := $(addprefix $(_4ddepends_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.d,$(filter %$(_ext),$(_4dsrcs)))))
5ddepends := $(addprefix $(_5ddepends_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.d,$(filter %$(_ext),$(_5dsrcs)))))
6ddepends := $(addprefix $(_6ddepends_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.d,$(filter %$(_ext),$(_6dsrcs)))))
mddepends := $(addprefix $(_mddepends_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.d,$(filter %$(_ext),$(_mdsrcs)))))

#assume that everything in the base directory is multidim in nature
_base_srcs := $(notdir $(wildcard $(foreach ext,$(src_extensions),$(addsuffix /*$(ext),$(base_dir)))))
mddepends += $(addprefix $(_mddepends_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.d,$(filter %$(_ext),$(_base_srcs)))))

depends = $(1ddepends) $(2ddepends) $(3ddepends) $(4ddepends) $(5ddepends) $(6ddepends) $(mddepends)

# the list of non-base object files that Make.rules will need to build
1dobjects := $(addprefix $(_1dobject_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.o,$(filter %$(_ext),$(_1dsrcs)))))
2dobjects := $(addprefix $(_2dobject_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.o,$(filter %$(_ext),$(_2dsrcs)))))
3dobjects := $(addprefix $(_3dobject_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.o,$(filter %$(_ext),$(_3dsrcs)))))
4dobjects := $(addprefix $(_4dobject_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.o,$(filter %$(_ext),$(_4dsrcs)))))
5dobjects := $(addprefix $(_5dobject_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.o,$(filter %$(_ext),$(_5dsrcs)))))
6dobjects := $(addprefix $(_6dobject_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.o,$(filter %$(_ext),$(_6dsrcs)))))
mdobjects := $(addprefix $(_mdobject_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.o,$(filter %$(_ext),$(_mdsrcs)))))

# if there is one name in $(mdebase) but other source files in $(base_dir), build them too (assumed to be multidim in nature)
# ifeq ($(words $(mdebase)),1)
#   _base_objs := $(addprefix $(_object_prefix),$(foreach _ext,$(src_extensions),$(subst $(_ext),.o,$(filter %$(_ext),$(_base_srcs)))))
#   mdobjects += $(filter-out o/$(newconfig)/$(mdebase).o,$(_base_objs))
# endif

objects = $(1dobjects) $(2dobjects) $(3dobjects) $(4dobjects) $(5dobjects) $(6dobjects) $(mdobjects)

local_base_object = $(patsubst %,o/$(newconfig)/%.o,$(mdebase))
local_app_objects = $(1dobjects) $(2dobjects) $(3dobjects) $(4dobjects) $(5dobjects) $(6dobjects) $(mdobjects) 

##
## targets

.PHONY: all example lib run vars usage

usage:
	@echo "This makefile supports targets:"
	@echo "     all example lib example-only run $(mdebase) vars usage"

# this is a bogus target which does nothing except updating the dependencies
# including regenerating any ChomboFortran header files which need to be updated.
# a hack, but a harmless hack (DFM-4/11/11)
createDependencies:

all example: all-example

lib: $(shell $(CHOMBO_HOME)/mk/reverse $(LibNames))

# tell program to run quietly unless user overrides on the command line
VERBOSE =

run: run-only

vars:
	@echo "CHOMBO_HOME=$(CHOMBO_HOME)"
	@echo "mdebase=$(mdebase)"
	@echo "LibNames=$(LibNames)"
	@echo "base_dir=$(base_dir)"
	@echo "src_dirs = $(src_dirs)"
	@echo "config=$(config)"
	@echo "objects=$(objects)"
	@echo "depends=$(depends)"
	@echo "appcppflags=$(appcppflags)"
	@echo "_srcs=$(_srcs)"
	@echo "_base_objs=$(_base_objs)"
	@echo "_base_srcs=$(_base_srcs)"
	@$(MAKE) --no-print-directory -f $(CHOMBO_HOME)/mk/Make.printVariables CHOMBO_HOME=$(CHOMBO_HOME) $@


# tell Make.rules not to compute object files automatically
AUTONAME=FALSE

$(mdebase) : $(mdebase).$(newconfig).ex

$(mdebase).$(newconfig).ex : $(local_base_object) $(local_app_objects)  $(shell $(CHOMBO_HOME)/mk/reverse $(all_libs)) 
	$(QUIET)$(CSHELLCMD) "$(LD) $(CXXFLAGS) $(XTRACXXFLAGS) $(LDFLAGS) $(XTRALDFLAGS) $< $(local_app_objects)  $(MDLIBFLAGS) $(XTRALIBFLAGS) $(cxxexeflag)$@ |&  awk -f $(CHOMBO_HOME)/mk/tempnam.awk"	


# This file exists solely to force creation of the subdirectories that
# hold the dependency, object and preprocessor files.
# NOTE: we cant use a dependency for this because .dummy will always
#       be out-of-date with respect to the subdirs because they are
#       modified after .dummy is created.  But since there are no
#       dependencies, this rule only runs when the file doesn't exist.
%/$(newconfig)/.dummy:
	$(ECHO)mkdir -p o/$(newconfig) f/$(newconfig) d/$(newconfig) p/$(newconfig)
	$(ECHO)touch $@

include $(CHOMBO_HOME)/mk/Make.rules
include $(CHOMBO_HOME)/mk/Make.rules.multidim
include $(CHOMBO_HOME)/mk/Make.rules.1d
include $(CHOMBO_HOME)/mk/Make.rules.2d
include $(CHOMBO_HOME)/mk/Make.rules.3d
include $(CHOMBO_HOME)/mk/Make.rules.4d
include $(CHOMBO_HOME)/mk/Make.rules.5d
include $(CHOMBO_HOME)/mk/Make.rules.6d

SECONDARY: d/$(newconfig)/.dummy d/$(1dconfig)/.dummy d/$(2dconfig)/.dummy d/$(3dconfig)/.dummy d/$(4dconfig)/.dummy d/$(5odconfig)/.dummy d/$(6dconfig)/.dummy

# this prevents "last chance rule" from firing

%:

